<?php
declare (strict_types = 1);
/**
 * Created by PhpStorm.
 * User: broceli
 * Date: 19-6-25
 * Time: 下午5:34
 */

namespace app\Lib\Jwt;

use Lcobucci\JWT\Builder;
use Lcobucci\JWT\ValidationData;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Token;
use Lcobucci\JWT\Signer\Hmac\Sha256;

class Jwt
{
    // 用户信息
    const JWT_USER = 'userInfo';

    /**
     * 文档地址 https://github.com/lcobucci/jwt/blob/3.2/README.md#basic-usage
     * @param $array
     * @param $uid
     * @return \Lcobucci\JWT\Token
     * @throws \ReflectionException
     * @throws \Swoft\Bean\Exception\ContainerException
     */
    public static function createToken(Array $array, $uid)
    {
        $signer = new Sha256();
        return (new Builder())
            ->setNotBefore(time() + 0)// 生成token之后多少时间内是无效的
            ->setExpiration(time() + 3600)// 过期时间 Configures the expiration time of the token
            ->set(self::JWT_USER, $array)// Configures a new claim, called "uid"
            ->sign($signer, static::getSignKey($uid)) // creates a signature using "testing" as key
            ->getToken(); // Retrieves the generated token
    }

    /**
     * 校验token & sign
     * @param Token $token
     * @param $uid
     * @return mixed
     * @throws \ReflectionException
     * @throws \Swoft\Bean\Exception\ContainerException
     */
    public static function validateToken(Token $token, $uid)
    {
        $signer = new Sha256();
        $data = new ValidationData();
        $data->setCurrentTime(time());
        try {
            if(!$token->verify($signer, static::getSignKey($uid))){
                throw new \Exception('sign校验失败');
            }
        } catch (\Exception $e) {
            throw $e;
        }
        return $token->validate($data);
    }

    /**
     * @param String $token
     * @return mixed
     */
    public static function parseToken(String $token)
    {
        return (new Parser())->parse((string)$token);
    }

    /**
     * 生成sign key的规则
     * @param $uid
     * @return string
     * @throws \ReflectionException
     * @throws \Swoft\Bean\Exception\ContainerException
     */
    public static function getSignKey($uid)
    {
        return "uid:{$uid}";
    }

}